/*************************************************
 * File name: sport_logic.c
 * Description: 业务逻辑实现
 *************************************************/
#include "sport_logic.h"
#include "sport_const.h"
#include <string.h>

double Logic_CalcScore(double base, int rank)
{
    switch (rank) {
        case 1: return base * SCORE_COEFF_1ST;
        case 2: return base * SCORE_COEFF_2ND;
        case 3: return base * SCORE_COEFF_3RD;
        default: return 0.0;
    }
}

static void SwapProject(ProjectNode **a, ProjectNode **b)
{
    ProjectNode *t = *a; *a = *b; *b = t;
}

void Logic_SortProjectById(ProjectList *head)
{
    if (!head || !*head || !(*head)->next) return;
    ProjectNode *arr[256];
    int n = 0;
    ProjectNode *p = *head;
    while (p && n < 256) { arr[n++] = p; p = p->next; }
    for (int i = 0; i < n - 1; ++i) {
        for (int j = 0; j < n - i - 1; ++j) {
            if (strcmp(arr[j]->id, arr[j + 1]->id) > 0)
                SwapProject(&arr[j], &arr[j + 1]);
        }
    }
    *head = arr[0];
    for (int i = 0; i < n - 1; ++i) arr[i]->next = arr[i + 1];
    arr[n - 1]->next = NULL;
}

static void SwapPlayer(PlayerNode **a, PlayerNode **b)
{
    PlayerNode *t = *a; *a = *b; *b = t;
}

void Logic_SortPlayerBySerial(PlayerList *head)
{
    if (!head || !*head || !(*head)->next) return;
    PlayerNode *arr[512];
    int n = 0;
    PlayerNode *p = *head;
    while (p && n < 512) { arr[n++] = p; p = p->next; }
    for (int i = 0; i < n - 1; ++i) {
        for (int j = 0; j < n - i - 1; ++j) {
            if (strcmp(arr[j]->serial, arr[j + 1]->serial) > 0)
                SwapPlayer(&arr[j], &arr[j + 1]);
        }
    }
    *head = arr[0];
    for (int i = 0; i < n - 1; ++i) arr[i]->next = arr[i + 1];
    arr[n - 1]->next = NULL;
}

void Logic_SortPlayerByDept(PlayerList *head)
{
    if (!head || !*head || !(*head)->next) return;
    PlayerNode *arr[512];
    int n = 0;
    PlayerNode *p = *head;
    while (p && n < 512) { arr[n++] = p; p = p->next; }
    for (int i = 0; i < n - 1; ++i) {
        for (int j = 0; j < n - i - 1; ++j) {
            if (strcmp(arr[j]->dept_id, arr[j + 1]->dept_id) > 0)
                SwapPlayer(&arr[j], &arr[j + 1]);
        }
    }
    *head = arr[0];
    for (int i = 0; i < n - 1; ++i) arr[i]->next = arr[i + 1];
    arr[n - 1]->next = NULL;
}

int Logic_StatByDept(PlayerList head, DeptStat *out, int max)
{
    int cnt = 0;
    for (PlayerNode *p = head; p; p = p->next) {
        int found = -1;
        for (int i = 0; i < cnt; ++i) {
            if (strcmp(out[i].dept_id, p->dept_id) == 0) {
                found = i; break;
            }
        }
        if (found == -1 && cnt < max) {
            strcpy(out[cnt].dept_id, p->dept_id);
            strcpy(out[cnt].dept_name, p->dept_name);
            out[cnt].total_score = p->grade;
            ++cnt;
        } else if (found != -1) {
            out[found].total_score += p->grade;
        }
    }
    return cnt;
}

int Logic_StatByProject(PlayerList head, DeptStat *out, int max)
{
    int cnt = 0;
    for (PlayerNode *p = head; p; p = p->next) {
        int found = -1;
        for (int i = 0; i < cnt; ++i) {
            if (strcmp(out[i].dept_id, p->proj_id) == 0) {
                found = i; break;
            }
        }
        if (found == -1 && cnt < max) {
            strcpy(out[cnt].dept_id, p->proj_id);
            strcpy(out[cnt].dept_name, p->proj_name);
            out[cnt].total_score = p->grade;
            ++cnt;
        } else if (found != -1) {
            out[found].total_score += p->grade;
        }
    }
    return cnt;
}

void Logic_ReviewApply(PlayerNode *node)
{
    if (node && strcmp(node->status, STATUS_PUBLIC) == 0)
        strcpy(node->status, STATUS_APPLY);
}

void Logic_ReviewOpinion(PlayerNode *node, double new_score)
{
    if (node && strcmp(node->status, STATUS_APPLY) == 0) {
        node->grade = new_score;
        strcpy(node->status, STATUS_REVIEWED);
    }
}